<!-- HTML header for doxygen 1.8.6-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<title>OpenCV: AKAZE local features matching</title>
<link href="../../opencv.ico" rel="shortcut icon" type="image/x-icon" />
<link href="../../tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../jquery.js"></script>
<script type="text/javascript" src="../../dynsections.js"></script>
<script type="text/javascript" src="../../tutorial-utils.js"></script>
<link href="../../search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../search/searchdata.js"></script>
<script type="text/javascript" src="../../search/search.js"></script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
//<![CDATA[
MathJax.Hub.Config(
{
  TeX: {
      Macros: {
          matTT: [ "\\[ \\left|\\begin{array}{ccc} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{array}\\right| \\]", 9],
          fork: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ \\end{array} \\right.", 4],
          forkthree: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ \\end{array} \\right.", 6],
          forkfour: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ #7 & \\mbox{#8}\\\\ \\end{array} \\right.", 8],
          vecthree: ["\\begin{bmatrix} #1\\\\ #2\\\\ #3 \\end{bmatrix}", 3],
          vecthreethree: ["\\begin{bmatrix} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{bmatrix}", 9],
          cameramatrix: ["#1 = \\begin{bmatrix} f_x & 0 & c_x\\\\ 0 & f_y & c_y\\\\ 0 & 0 & 1 \\end{bmatrix}", 1],
          distcoeffs: ["(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \\tau_x, \\tau_y]]]]) \\text{ of 4, 5, 8, 12 or 14 elements}"],
          distcoeffsfisheye: ["(k_1, k_2, k_3, k_4)"],
          hdotsfor: ["\\dots", 1],
          mathbbm: ["\\mathbb{#1}", 1],
          bordermatrix: ["\\matrix{#1}", 1]
      }
  }
}
);
//]]>
</script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js"></script>
<link href="../../doxygen.css" rel="stylesheet" type="text/css" />
<link href="../../stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<!--#include virtual="/google-search.html"-->
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="../../opencv-logo-small.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">OpenCV
   &#160;<span id="projectnumber">4.5.2</span>
   </div>
   <div id="projectbrief">Open Source Computer Vision</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "../../search",false,'Search');
</script>
<script type="text/javascript" src="../../menudata.js"></script>
<script type="text/javascript" src="../../menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('../../',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="../../d9/df8/tutorial_root.html">OpenCV Tutorials</a></li><li class="navelem"><a class="el" href="../../d9/d97/tutorial_table_of_content_features2d.html">2D Features framework (feature2d module)</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">AKAZE local features matching </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p><b>Prev Tutorial:</b> <a class="el" href="../../dd/dd4/tutorial_detection_of_planar_objects.html">Detection of planar objects</a></p>
<p><b>Next Tutorial:</b> <a class="el" href="../../dc/d16/tutorial_akaze_tracking.html">AKAZE and ORB planar tracking</a></p>
<table class="doxtable">
<tr>
<th align="right"></th><th align="left"></th></tr>
<tr>
<td align="right">Original author </td><td align="left">Fedor Morozov </td></tr>
<tr>
<td align="right">Compatibility </td><td align="left">OpenCV &gt;= 3.0 </td></tr>
</table>
<h2>Introduction </h2>
<p>In this tutorial we will learn how to use AKAZE <a class="el" href="../../d0/de3/citelist.html#CITEREF_ANB13">[9]</a> local features to detect and match keypoints on two images. We will find keypoints on a pair of images with given homography matrix, match them and count the number of inliers (i.e. matches that fit in the given homography).</p>
<p>You can find expanded version of this example here: <a href="https://github.com/pablofdezalc/test_kaze_akaze_opencv">https://github.com/pablofdezalc/test_kaze_akaze_opencv</a></p>
<h2>Data </h2>
<p>We are going to use images 1 and 3 from <em>Graffiti</em> sequence of <a href="http://www.robots.ox.ac.uk/~vgg/data/data-aff.html">Oxford dataset</a>.</p>
<div class="image">
<img src="../../graf.png" alt="graf.png"/>
</div>
<p>Homography is given by a 3 by 3 matrix: </p><div class="fragment"><div class="line">7.6285898e-01  -2.9922929e-01   2.2567123e+02</div><div class="line">3.3443473e-01   1.0143901e+00  -7.6999973e+01</div><div class="line">3.4663091e-04  -1.4364524e-05   1.0000000e+00</div></div><!-- fragment --><p> You can find the images (<em>graf1.png</em>, <em>graf3.png</em>) and homography (<em>H1to3p.xml</em>) in <em>opencv/samples/data/</em>.</p>
<h3>Source Code</h3>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'><ul>
<li><b>Downloadable code</b>: Click <a href="https://raw.githubusercontent.com/opencv/opencv/master/samples/cpp/tutorial_code/features2D/AKAZE_match.cpp">here</a></li>
<li><b>Code at glance:</b> <div class="fragment"><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../d5/d0d/features2d_8hpp.html">opencv2/features2d.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../d1/d4f/imgproc_2include_2opencv2_2imgproc_8hpp.html">opencv2/imgproc.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;<a class="code" href="../../d4/dd5/highgui_8hpp.html">opencv2/highgui.hpp</a>&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;iostream&gt;</span></div><div class="line"></div><div class="line"><span class="keyword">using namespace </span>std;</div><div class="line"><span class="keyword">using namespace </span><a class="code" href="../../d2/d75/namespacecv.html">cv</a>;</div><div class="line"></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">float</span> inlier_threshold = 2.5f; <span class="comment">// Distance threshold to identify inliers with homography check</span></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">float</span> nn_match_ratio = 0.8f;   <span class="comment">// Nearest neighbor matching ratio</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span>* argv[])</div><div class="line">{</div><div class="line">    <a class="code" href="../../d0/d2e/classcv_1_1CommandLineParser.html">CommandLineParser</a> parser(argc, argv,</div><div class="line">                             <span class="stringliteral">&quot;{@img1 | graf1.png | input image 1}&quot;</span></div><div class="line">                             <span class="stringliteral">&quot;{@img2 | graf3.png | input image 2}&quot;</span></div><div class="line">                             <span class="stringliteral">&quot;{@homography | H1to3p.xml | homography matrix}&quot;</span>);</div><div class="line">    <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> img1 = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">imread</a>( <a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">samples::findFile</a>( parser.get&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;(<span class="stringliteral">&quot;@img1&quot;</span>) ), <a class="code" href="../../d8/d6a/group__imgcodecs__flags.html#gga61d9b0126a3e57d9277ac48327799c80ae29981cfc153d3b0cef5c0daeedd2125">IMREAD_GRAYSCALE</a>);</div><div class="line">    <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> img2 = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">imread</a>( <a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">samples::findFile</a>( parser.get&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;(<span class="stringliteral">&quot;@img2&quot;</span>) ), <a class="code" href="../../d8/d6a/group__imgcodecs__flags.html#gga61d9b0126a3e57d9277ac48327799c80ae29981cfc153d3b0cef5c0daeedd2125">IMREAD_GRAYSCALE</a>);</div><div class="line"></div><div class="line">    <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> homography;</div><div class="line">    <a class="code" href="../../da/d56/classcv_1_1FileStorage.html">FileStorage</a> fs( <a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">samples::findFile</a>( parser.get&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;(<span class="stringliteral">&quot;@homography&quot;</span>) ), FileStorage::READ);</div><div class="line">    fs.getFirstTopLevelNode() &gt;&gt; homography;</div><div class="line"></div><div class="line">    vector&lt;KeyPoint&gt; kpts1, kpts2;</div><div class="line">    <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> desc1, desc2;</div><div class="line"></div><div class="line">    <a class="code" href="../../dc/d84/group__core__basic.html#ga6395ca871a678020c4a31fadf7e8cc63">Ptr&lt;AKAZE&gt;</a> akaze = AKAZE::create();</div><div class="line">    akaze-&gt;detectAndCompute(img1, <a class="code" href="../../dc/d84/group__core__basic.html#gad9287b23bba2fed753b36ef561ae7346">noArray</a>(), kpts1, desc1);</div><div class="line">    akaze-&gt;detectAndCompute(img2, <a class="code" href="../../dc/d84/group__core__basic.html#gad9287b23bba2fed753b36ef561ae7346">noArray</a>(), kpts2, desc2);</div><div class="line"></div><div class="line">    <a class="code" href="../../d3/da1/classcv_1_1BFMatcher.html">BFMatcher</a> matcher(<a class="code" href="../../d2/de8/group__core__array.html#ggad12cefbcb5291cf958a85b4b67b6149fa4b063afd04aebb8dd07085a1207da727">NORM_HAMMING</a>);</div><div class="line">    vector&lt; vector&lt;DMatch&gt; &gt; nn_matches;</div><div class="line">    matcher.knnMatch(desc1, desc2, nn_matches, 2);</div><div class="line"></div><div class="line">    vector&lt;KeyPoint&gt; matched1, matched2;</div><div class="line">    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; nn_matches.size(); i++) {</div><div class="line">        <a class="code" href="../../d4/de0/classcv_1_1DMatch.html">DMatch</a> first = nn_matches[i][0];</div><div class="line">        <span class="keywordtype">float</span> dist1 = nn_matches[i][0].distance;</div><div class="line">        <span class="keywordtype">float</span> dist2 = nn_matches[i][1].distance;</div><div class="line"></div><div class="line">        <span class="keywordflow">if</span>(dist1 &lt; nn_match_ratio * dist2) {</div><div class="line">            matched1.push_back(kpts1[first.<a class="code" href="../../d4/de0/classcv_1_1DMatch.html#a47475576327f6ba9cd39250881b4d330">queryIdx</a>]);</div><div class="line">            matched2.push_back(kpts2[first.<a class="code" href="../../d4/de0/classcv_1_1DMatch.html#a2320bcc822280c8a416b85f80f5a4453">trainIdx</a>]);</div><div class="line">        }</div><div class="line">    }</div><div class="line"></div><div class="line">    vector&lt;DMatch&gt; good_matches;</div><div class="line">    vector&lt;KeyPoint&gt; inliers1, inliers2;</div><div class="line">    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; matched1.size(); i++) {</div><div class="line">        <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> col = Mat::ones(3, 1, <a class="code" href="../../d1/d1b/group__core__hal__interface.html#ga30a562691cc5987bc88eb7bb7a8faf2b">CV_64F</a>);</div><div class="line">        col.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#aa5d20fc86d41d59e4d71ae93daee9726">at</a>&lt;<span class="keywordtype">double</span>&gt;(0) = matched1[i].pt.x;</div><div class="line">        col.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#aa5d20fc86d41d59e4d71ae93daee9726">at</a>&lt;<span class="keywordtype">double</span>&gt;(1) = matched1[i].pt.y;</div><div class="line"></div><div class="line">        col = homography * col;</div><div class="line">        col /= col.<a class="code" href="../../d3/d63/classcv_1_1Mat.html#aa5d20fc86d41d59e4d71ae93daee9726">at</a>&lt;<span class="keywordtype">double</span>&gt;(2);</div><div class="line">        <span class="keywordtype">double</span> dist = <a class="code" href="../../d0/de1/group__core.html#ga9070b6a3f093dd952d973819b06f4906">sqrt</a>( <a class="code" href="../../d7/dcc/group__core__utils__softfloat.html#ga8bc36646a43b82baa15f151a973fb0c5">pow</a>(col.at&lt;<span class="keywordtype">double</span>&gt;(0) - matched2[i].pt.x, 2) +</div><div class="line">                            <a class="code" href="../../d7/dcc/group__core__utils__softfloat.html#ga8bc36646a43b82baa15f151a973fb0c5">pow</a>(col.at&lt;<span class="keywordtype">double</span>&gt;(1) - matched2[i].pt.y, 2));</div><div class="line"></div><div class="line">        <span class="keywordflow">if</span>(dist &lt; inlier_threshold) {</div><div class="line">            <span class="keywordtype">int</span> new_i = <span class="keyword">static_cast&lt;</span><span class="keywordtype">int</span><span class="keyword">&gt;</span>(inliers1.size());</div><div class="line">            inliers1.push_back(matched1[i]);</div><div class="line">            inliers2.push_back(matched2[i]);</div><div class="line">            good_matches.push_back(<a class="code" href="../../d4/de0/classcv_1_1DMatch.html">DMatch</a>(new_i, new_i, 0));</div><div class="line">        }</div><div class="line">    }</div><div class="line"></div><div class="line">    <a class="code" href="../../d3/d63/classcv_1_1Mat.html">Mat</a> res;</div><div class="line">    <a class="code" href="../../d4/d5d/group__features2d__draw.html#gad8f463ccaf0dc6f61083abd8717c261a">drawMatches</a>(img1, inliers1, img2, inliers2, good_matches, res);</div><div class="line">    <a class="code" href="../../d4/da8/group__imgcodecs.html#gabbc7ef1aa2edfaa87772f1202d67e0ce">imwrite</a>(<span class="stringliteral">&quot;akaze_result.png&quot;</span>, res);</div><div class="line"></div><div class="line">    <span class="keywordtype">double</span> inlier_ratio = inliers1.size() / (double) matched1.size();</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;A-KAZE Matching Results&quot;</span> &lt;&lt; endl;</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;*******************************&quot;</span> &lt;&lt; endl;</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;# Keypoints 1:                        \t&quot;</span> &lt;&lt; kpts1.size() &lt;&lt; endl;</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;# Keypoints 2:                        \t&quot;</span> &lt;&lt; kpts2.size() &lt;&lt; endl;</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;# Matches:                            \t&quot;</span> &lt;&lt; matched1.size() &lt;&lt; endl;</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;# Inliers:                            \t&quot;</span> &lt;&lt; inliers1.size() &lt;&lt; endl;</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;# Inliers Ratio:                      \t&quot;</span> &lt;&lt; inlier_ratio &lt;&lt; endl;</div><div class="line">    cout &lt;&lt; endl;</div><div class="line"></div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#ga453d42fe4cb60e5723281a89973ee563">imshow</a>(<span class="stringliteral">&quot;result&quot;</span>, res);</div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba38bd7">waitKey</a>();</div><div class="line"></div><div class="line">    <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment -->  </div> </li>
</ul>
 <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'><ul>
<li><b>Downloadable code</b>: Click <a href="https://raw.githubusercontent.com/opencv/opencv/master/samples/java/tutorial_code/features2D/akaze_matching/AKAZEMatchDemo.java">here</a></li>
<li><b>Code at glance:</b> <div class="fragment"><div class="line"><span class="keyword">import</span> java.io.File;</div><div class="line"><span class="keyword">import</span> java.io.IOException;</div><div class="line"><span class="keyword">import</span> java.util.ArrayList;</div><div class="line"><span class="keyword">import</span> java.util.List;</div><div class="line"></div><div class="line"><span class="keyword">import</span> javax.xml.parsers.DocumentBuilder;</div><div class="line"><span class="keyword">import</span> javax.xml.parsers.DocumentBuilderFactory;</div><div class="line"><span class="keyword">import</span> javax.xml.parsers.ParserConfigurationException;</div><div class="line"></div><div class="line"><span class="keyword">import</span> org.opencv.core.Core;</div><div class="line"><span class="keyword">import</span> org.opencv.core.CvType;</div><div class="line"><span class="keyword">import</span> org.opencv.core.DMatch;</div><div class="line"><span class="keyword">import</span> org.opencv.core.KeyPoint;</div><div class="line"><span class="keyword">import</span> org.opencv.core.Mat;</div><div class="line"><span class="keyword">import</span> org.opencv.core.MatOfDMatch;</div><div class="line"><span class="keyword">import</span> org.opencv.core.MatOfKeyPoint;</div><div class="line"><span class="keyword">import</span> org.opencv.core.Scalar;</div><div class="line"><span class="keyword">import</span> org.opencv.features2d.AKAZE;</div><div class="line"><span class="keyword">import</span> org.opencv.features2d.DescriptorMatcher;</div><div class="line"><span class="keyword">import</span> org.opencv.features2d.Features2d;</div><div class="line"><span class="keyword">import</span> org.opencv.highgui.HighGui;</div><div class="line"><span class="keyword">import</span> org.opencv.imgcodecs.Imgcodecs;</div><div class="line"><span class="keyword">import</span> org.w3c.dom.Document;</div><div class="line"><span class="keyword">import</span> org.xml.sax.SAXException;</div><div class="line"></div><div class="line"><span class="keyword">class </span>AKAZEMatch {</div><div class="line">    <span class="keyword">public</span> <span class="keywordtype">void</span> run(<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>[] args) {</div><div class="line">        <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> filename1 = args.length &gt; 2 ? args[0] : <span class="stringliteral">&quot;../data/graf1.png&quot;</span>;</div><div class="line">        <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> filename2 = args.length &gt; 2 ? args[1] : <span class="stringliteral">&quot;../data/graf3.png&quot;</span>;</div><div class="line">        <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> filename3 = args.length &gt; 2 ? args[2] : <span class="stringliteral">&quot;../data/H1to3p.xml&quot;</span>;</div><div class="line">        Mat img1 = Imgcodecs.imread(filename1, Imgcodecs.IMREAD_GRAYSCALE);</div><div class="line">        Mat img2 = Imgcodecs.imread(filename2, Imgcodecs.IMREAD_GRAYSCALE);</div><div class="line">        <span class="keywordflow">if</span> (img1.empty() || img2.empty()) {</div><div class="line">            System.err.println(<span class="stringliteral">&quot;Cannot read images!&quot;</span>);</div><div class="line">            System.exit(0);</div><div class="line">        }</div><div class="line"></div><div class="line">        File file = <span class="keyword">new</span> File(filename3);</div><div class="line">        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();</div><div class="line">        DocumentBuilder documentBuilder;</div><div class="line">        Document document;</div><div class="line">        Mat homography = <span class="keyword">new</span> Mat(3, 3, CvType.CV_64F);</div><div class="line">        <span class="keywordtype">double</span>[] homographyData = <span class="keyword">new</span> <span class="keywordtype">double</span>[(int) (homography.total()*homography.channels())];</div><div class="line">        <span class="keywordflow">try</span> {</div><div class="line">            documentBuilder = documentBuilderFactory.newDocumentBuilder();</div><div class="line">            document = documentBuilder.parse(file);</div><div class="line">            <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> homographyStr = document.getElementsByTagName(<span class="stringliteral">&quot;data&quot;</span>).item(0).getTextContent();</div><div class="line">            <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>[] splited = homographyStr.split(<span class="stringliteral">&quot;\\s+&quot;</span>);</div><div class="line">            <span class="keywordtype">int</span> idx = 0;</div><div class="line">            <span class="keywordflow">for</span> (<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> s : splited) {</div><div class="line">                <span class="keywordflow">if</span> (!s.isEmpty()) {</div><div class="line">                    homographyData[idx] = Double.parseDouble(s);</div><div class="line">                    idx++;</div><div class="line">                }</div><div class="line">            }</div><div class="line">        } <span class="keywordflow">catch</span> (ParserConfigurationException e) {</div><div class="line">            e.printStackTrace();</div><div class="line">            System.exit(0);</div><div class="line">        } <span class="keywordflow">catch</span> (SAXException e) {</div><div class="line">            e.printStackTrace();</div><div class="line">            System.exit(0);</div><div class="line">        } <span class="keywordflow">catch</span> (IOException e) {</div><div class="line">            e.printStackTrace();</div><div class="line">            System.exit(0);</div><div class="line">        }</div><div class="line">        homography.put(0, 0, homographyData);</div><div class="line"></div><div class="line">        AKAZE akaze = AKAZE.create();</div><div class="line">        MatOfKeyPoint kpts1 = <span class="keyword">new</span> MatOfKeyPoint(), kpts2 = <span class="keyword">new</span> MatOfKeyPoint();</div><div class="line">        Mat desc1 = <span class="keyword">new</span> Mat(), desc2 = <span class="keyword">new</span> Mat();</div><div class="line">        akaze.detectAndCompute(img1, <span class="keyword">new</span> Mat(), kpts1, desc1);</div><div class="line">        akaze.detectAndCompute(img2, <span class="keyword">new</span> Mat(), kpts2, desc2);</div><div class="line"></div><div class="line">        DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);</div><div class="line">        List&lt;MatOfDMatch&gt; knnMatches = <span class="keyword">new</span> ArrayList&lt;&gt;();</div><div class="line">        matcher.knnMatch(desc1, desc2, knnMatches, 2);</div><div class="line"></div><div class="line">        <span class="keywordtype">float</span> ratioThreshold = 0.8f; <span class="comment">// Nearest neighbor matching ratio</span></div><div class="line">        List&lt;KeyPoint&gt; listOfMatched1 = <span class="keyword">new</span> ArrayList&lt;&gt;();</div><div class="line">        List&lt;KeyPoint&gt; listOfMatched2 = <span class="keyword">new</span> ArrayList&lt;&gt;();</div><div class="line">        List&lt;KeyPoint&gt; listOfKeypoints1 = kpts1.toList();</div><div class="line">        List&lt;KeyPoint&gt; listOfKeypoints2 = kpts2.toList();</div><div class="line">        <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; knnMatches.size(); i++) {</div><div class="line">            DMatch[] matches = knnMatches.get(i).toArray();</div><div class="line">            <span class="keywordtype">float</span> dist1 = matches[0].distance;</div><div class="line">            <span class="keywordtype">float</span> dist2 = matches[1].distance;</div><div class="line">            <span class="keywordflow">if</span> (dist1 &lt; ratioThreshold * dist2) {</div><div class="line">                listOfMatched1.add(listOfKeypoints1.get(matches[0].queryIdx));</div><div class="line">                listOfMatched2.add(listOfKeypoints2.get(matches[0].trainIdx));</div><div class="line">            }</div><div class="line">        }</div><div class="line"></div><div class="line">        <span class="keywordtype">double</span> inlierThreshold = 2.5; <span class="comment">// Distance threshold to identify inliers with homography check</span></div><div class="line">        List&lt;KeyPoint&gt; listOfInliers1 = <span class="keyword">new</span> ArrayList&lt;&gt;();</div><div class="line">        List&lt;KeyPoint&gt; listOfInliers2 = <span class="keyword">new</span> ArrayList&lt;&gt;();</div><div class="line">        List&lt;DMatch&gt; listOfGoodMatches = <span class="keyword">new</span> ArrayList&lt;&gt;();</div><div class="line">        <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; listOfMatched1.size(); i++) {</div><div class="line">            Mat col = <span class="keyword">new</span> Mat(3, 1, CvType.CV_64F);</div><div class="line">            <span class="keywordtype">double</span>[] colData = <span class="keyword">new</span> <span class="keywordtype">double</span>[(int) (col.total() * col.channels())];</div><div class="line">            colData[0] = listOfMatched1.get(i).pt.x;</div><div class="line">            colData[1] = listOfMatched1.get(i).pt.y;</div><div class="line">            colData[2] = 1.0;</div><div class="line">            col.put(0, 0, colData);</div><div class="line"></div><div class="line">            Mat colRes = <span class="keyword">new</span> Mat();</div><div class="line">            Core.gemm(homography, col, 1.0, <span class="keyword">new</span> Mat(), 0.0, colRes);</div><div class="line">            colRes.get(0, 0, colData);</div><div class="line">            Core.multiply(colRes, <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>(1.0 / colData[2]), col);</div><div class="line">            col.get(0, 0, colData);</div><div class="line"></div><div class="line">            <span class="keywordtype">double</span> dist = Math.sqrt(Math.pow(colData[0] - listOfMatched2.get(i).pt.x, 2) +</div><div class="line">                    Math.pow(colData[1] - listOfMatched2.get(i).pt.y, 2));</div><div class="line"></div><div class="line">            <span class="keywordflow">if</span> (dist &lt; inlierThreshold) {</div><div class="line">                listOfGoodMatches.add(<span class="keyword">new</span> DMatch(listOfInliers1.size(), listOfInliers2.size(), 0));</div><div class="line">                listOfInliers1.add(listOfMatched1.get(i));</div><div class="line">                listOfInliers2.add(listOfMatched2.get(i));</div><div class="line">            }</div><div class="line">        }</div><div class="line"></div><div class="line">        Mat res = <span class="keyword">new</span> Mat();</div><div class="line">        MatOfKeyPoint inliers1 = <span class="keyword">new</span> MatOfKeyPoint(listOfInliers1.toArray(<span class="keyword">new</span> KeyPoint[listOfInliers1.size()]));</div><div class="line">        MatOfKeyPoint inliers2 = <span class="keyword">new</span> MatOfKeyPoint(listOfInliers2.toArray(<span class="keyword">new</span> KeyPoint[listOfInliers2.size()]));</div><div class="line">        MatOfDMatch goodMatches = <span class="keyword">new</span> MatOfDMatch(listOfGoodMatches.toArray(<span class="keyword">new</span> DMatch[listOfGoodMatches.size()]));</div><div class="line">        Features2d.drawMatches(img1, inliers1, img2, inliers2, goodMatches, res);</div><div class="line">        Imgcodecs.imwrite(<span class="stringliteral">&quot;akaze_result.png&quot;</span>, res);</div><div class="line"></div><div class="line">        <span class="keywordtype">double</span> inlierRatio = listOfInliers1.size() / (double) listOfMatched1.size();</div><div class="line">        System.out.println(<span class="stringliteral">&quot;A-KAZE Matching Results&quot;</span>);</div><div class="line">        System.out.println(<span class="stringliteral">&quot;*******************************&quot;</span>);</div><div class="line">        System.out.println(<span class="stringliteral">&quot;# Keypoints 1:                        \t&quot;</span> + listOfKeypoints1.size());</div><div class="line">        System.out.println(<span class="stringliteral">&quot;# Keypoints 2:                        \t&quot;</span> + listOfKeypoints2.size());</div><div class="line">        System.out.println(<span class="stringliteral">&quot;# Matches:                            \t&quot;</span> + listOfMatched1.size());</div><div class="line">        System.out.println(<span class="stringliteral">&quot;# Inliers:                            \t&quot;</span> + listOfInliers1.size());</div><div class="line">        System.out.println(<span class="stringliteral">&quot;# Inliers Ratio:                      \t&quot;</span> + inlierRatio);</div><div class="line"></div><div class="line">        HighGui.imshow(<span class="stringliteral">&quot;result&quot;</span>, res);</div><div class="line">        HighGui.waitKey();</div><div class="line"></div><div class="line">        System.exit(0);</div><div class="line">    }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">public</span> <span class="keyword">class </span>AKAZEMatchDemo {</div><div class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keywordtype">void</span> main(<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>[] args) {</div><div class="line">        <span class="comment">// Load the native OpenCV library</span></div><div class="line">        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);</div><div class="line"></div><div class="line">        <span class="keyword">new</span> AKAZEMatch().run(args);</div><div class="line">    }</div><div class="line">}</div></div><!-- fragment -->  </div> </li>
</ul>
 <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'><ul>
<li><b>Downloadable code</b>: Click <a href="https://raw.githubusercontent.com/opencv/opencv/master/samples/python/tutorial_code/features2D/akaze_matching/AKAZE_match.py">here</a></li>
<li><b>Code at glance:</b> <div class="fragment"><div class="line"><span class="keyword">from</span> __future__ <span class="keyword">import</span> print_function</div><div class="line"><span class="keyword">import</span> cv2 <span class="keyword">as</span> cv</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> argparse</div><div class="line"><span class="keyword">from</span> math <span class="keyword">import</span> sqrt</div><div class="line"></div><div class="line"></div><div class="line">parser = argparse.ArgumentParser(description=<span class="stringliteral">&#39;Code for AKAZE local features matching tutorial.&#39;</span>)</div><div class="line">parser.add_argument(<span class="stringliteral">&#39;--input1&#39;</span>, help=<span class="stringliteral">&#39;Path to input image 1.&#39;</span>, default=<span class="stringliteral">&#39;graf1.png&#39;</span>)</div><div class="line">parser.add_argument(<span class="stringliteral">&#39;--input2&#39;</span>, help=<span class="stringliteral">&#39;Path to input image 2.&#39;</span>, default=<span class="stringliteral">&#39;graf3.png&#39;</span>)</div><div class="line">parser.add_argument(<span class="stringliteral">&#39;--homography&#39;</span>, help=<span class="stringliteral">&#39;Path to the homography matrix.&#39;</span>, default=<span class="stringliteral">&#39;H1to3p.xml&#39;</span>)</div><div class="line">args = parser.parse_args()</div><div class="line"></div><div class="line">img1 = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">cv.imread</a>(<a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">cv.samples.findFile</a>(args.input1), cv.IMREAD_GRAYSCALE)</div><div class="line">img2 = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">cv.imread</a>(<a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">cv.samples.findFile</a>(args.input2), cv.IMREAD_GRAYSCALE)</div><div class="line"><span class="keywordflow">if</span> img1 <span class="keywordflow">is</span> <span class="keywordtype">None</span> <span class="keywordflow">or</span> img2 <span class="keywordflow">is</span> <span class="keywordtype">None</span>:</div><div class="line">    <a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;Could not open or find the images!&#39;</span>)</div><div class="line">    exit(0)</div><div class="line"></div><div class="line">fs = <a class="code" href="../../da/d56/classcv_1_1FileStorage.html">cv.FileStorage</a>(<a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">cv.samples.findFile</a>(args.homography), cv.FILE_STORAGE_READ)</div><div class="line">homography = fs.getFirstTopLevelNode().mat()</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line">akaze = cv.AKAZE_create()</div><div class="line">kpts1, desc1 = akaze.detectAndCompute(img1, <span class="keywordtype">None</span>)</div><div class="line">kpts2, desc2 = akaze.detectAndCompute(img2, <span class="keywordtype">None</span>)</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line">matcher = cv.DescriptorMatcher_create(cv.DescriptorMatcher_BRUTEFORCE_HAMMING)</div><div class="line">nn_matches = matcher.knnMatch(desc1, desc2, 2)</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line">matched1 = []</div><div class="line">matched2 = []</div><div class="line">nn_match_ratio = 0.8 <span class="comment"># Nearest neighbor matching ratio</span></div><div class="line"><span class="keywordflow">for</span> m, n <span class="keywordflow">in</span> nn_matches:</div><div class="line">    <span class="keywordflow">if</span> m.distance &lt; nn_match_ratio * n.distance:</div><div class="line">        matched1.append(kpts1[m.queryIdx])</div><div class="line">        matched2.append(kpts2[m.trainIdx])</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line">inliers1 = []</div><div class="line">inliers2 = []</div><div class="line">good_matches = []</div><div class="line">inlier_threshold = 2.5 <span class="comment"># Distance threshold to identify inliers with homography check</span></div><div class="line"><span class="keywordflow">for</span> i, m <span class="keywordflow">in</span> enumerate(matched1):</div><div class="line">    col = np.ones((3,1), dtype=np.float64)</div><div class="line">    col[0:2,0] = m.pt</div><div class="line"></div><div class="line">    col = np.dot(homography, col)</div><div class="line">    col /= col[2,0]</div><div class="line">    dist = <a class="code" href="../../d0/de1/group__core.html#ga9070b6a3f093dd952d973819b06f4906">sqrt</a>(<a class="code" href="../../d7/dcc/group__core__utils__softfloat.html#ga8bc36646a43b82baa15f151a973fb0c5">pow</a>(col[0,0] - matched2[i].pt[0], 2) +\</div><div class="line">                <a class="code" href="../../d7/dcc/group__core__utils__softfloat.html#ga8bc36646a43b82baa15f151a973fb0c5">pow</a>(col[1,0] - matched2[i].pt[1], 2))</div><div class="line"></div><div class="line">    <span class="keywordflow">if</span> dist &lt; inlier_threshold:</div><div class="line">        good_matches.append(<a class="code" href="../../d4/de0/classcv_1_1DMatch.html">cv.DMatch</a>(len(inliers1), len(inliers2), 0))</div><div class="line">        inliers1.append(matched1[i])</div><div class="line">        inliers2.append(matched2[i])</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line">res = np.empty((<a class="code" href="../../d1/d10/classcv_1_1MatExpr.html#a6dff8b6e9105b6d817b493e7be157c90">max</a>(img1.shape[0], img2.shape[0]), img1.shape[1]+img2.shape[1], 3), dtype=np.uint8)</div><div class="line"><a class="code" href="../../d4/d5d/group__features2d__draw.html#ga62fbedb5206ab2faf411797e7055c90f">cv.drawMatches</a>(img1, inliers1, img2, inliers2, good_matches, res)</div><div class="line"><a class="code" href="../../d4/da8/group__imgcodecs.html#gabbc7ef1aa2edfaa87772f1202d67e0ce">cv.imwrite</a>(<span class="stringliteral">&quot;akaze_result.png&quot;</span>, res)</div><div class="line"></div><div class="line">inlier_ratio = len(inliers1) / float(len(matched1))</div><div class="line"><a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;A-KAZE Matching Results&#39;</span>)</div><div class="line"><a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;*******************************&#39;</span>)</div><div class="line"><a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;# Keypoints 1:                        \t&#39;</span>, len(kpts1))</div><div class="line"><a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;# Keypoints 2:                        \t&#39;</span>, len(kpts2))</div><div class="line"><a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;# Matches:                            \t&#39;</span>, len(matched1))</div><div class="line"><a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;# Inliers:                            \t&#39;</span>, len(inliers1))</div><div class="line"><a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;# Inliers Ratio:                      \t&#39;</span>, inlier_ratio)</div><div class="line"></div><div class="line"><a class="code" href="../../df/d24/group__highgui__opengl.html#gaae7e90aa3415c68dba22a5ff2cefc25d">cv.imshow</a>(<span class="stringliteral">&#39;result&#39;</span>, res)</div><div class="line"><a class="code" href="../../d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba38bd7">cv.waitKey</a>()</div><div class="line"></div></div><!-- fragment -->  </div> </li>
</ul>
<h3>Explanation</h3>
<ul>
<li><b>Load images and homography</b></li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    CommandLineParser parser(argc, argv,</div><div class="line">                             <span class="stringliteral">&quot;{@img1 | graf1.png | input image 1}&quot;</span></div><div class="line">                             <span class="stringliteral">&quot;{@img2 | graf3.png | input image 2}&quot;</span></div><div class="line">                             <span class="stringliteral">&quot;{@homography | H1to3p.xml | homography matrix}&quot;</span>);</div><div class="line">    Mat img1 = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">imread</a>( <a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">samples::findFile</a>( parser.get&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;(<span class="stringliteral">&quot;@img1&quot;</span>) ), <a class="code" href="../../d8/d6a/group__imgcodecs__flags.html#gga61d9b0126a3e57d9277ac48327799c80ae29981cfc153d3b0cef5c0daeedd2125">IMREAD_GRAYSCALE</a>);</div><div class="line">    Mat img2 = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">imread</a>( <a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">samples::findFile</a>( parser.get&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;(<span class="stringliteral">&quot;@img2&quot;</span>) ), <a class="code" href="../../d8/d6a/group__imgcodecs__flags.html#gga61d9b0126a3e57d9277ac48327799c80ae29981cfc153d3b0cef5c0daeedd2125">IMREAD_GRAYSCALE</a>);</div><div class="line"></div><div class="line">    Mat homography;</div><div class="line">    FileStorage fs( <a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">samples::findFile</a>( parser.get&lt;<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>&gt;(<span class="stringliteral">&quot;@homography&quot;</span>) ), FileStorage::READ);</div><div class="line">    fs.getFirstTopLevelNode() &gt;&gt; homography;</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> filename1 = args.length &gt; 2 ? args[0] : <span class="stringliteral">&quot;../data/graf1.png&quot;</span>;</div><div class="line">        <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> filename2 = args.length &gt; 2 ? args[1] : <span class="stringliteral">&quot;../data/graf3.png&quot;</span>;</div><div class="line">        <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> filename3 = args.length &gt; 2 ? args[2] : <span class="stringliteral">&quot;../data/H1to3p.xml&quot;</span>;</div><div class="line">        Mat img1 = Imgcodecs.imread(filename1, Imgcodecs.IMREAD_GRAYSCALE);</div><div class="line">        Mat img2 = Imgcodecs.imread(filename2, Imgcodecs.IMREAD_GRAYSCALE);</div><div class="line">        <span class="keywordflow">if</span> (img1.empty() || img2.empty()) {</div><div class="line">            System.err.println(<span class="stringliteral">&quot;Cannot read images!&quot;</span>);</div><div class="line">            System.exit(0);</div><div class="line">        }</div><div class="line"></div><div class="line">        File file = <span class="keyword">new</span> File(filename3);</div><div class="line">        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();</div><div class="line">        DocumentBuilder documentBuilder;</div><div class="line">        Document document;</div><div class="line">        Mat homography = <span class="keyword">new</span> Mat(3, 3, CvType.CV_64F);</div><div class="line">        <span class="keywordtype">double</span>[] homographyData = <span class="keyword">new</span> <span class="keywordtype">double</span>[(int) (homography.total()*homography.channels())];</div><div class="line">        <span class="keywordflow">try</span> {</div><div class="line">            documentBuilder = documentBuilderFactory.newDocumentBuilder();</div><div class="line">            document = documentBuilder.parse(file);</div><div class="line">            <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> homographyStr = document.getElementsByTagName(<span class="stringliteral">&quot;data&quot;</span>).item(0).getTextContent();</div><div class="line">            <a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a>[] splited = homographyStr.split(<span class="stringliteral">&quot;\\s+&quot;</span>);</div><div class="line">            <span class="keywordtype">int</span> idx = 0;</div><div class="line">            <span class="keywordflow">for</span> (<a class="code" href="../../dc/d84/group__core__basic.html#ga1f6634802eeadfd7245bc75cf3e216c2">String</a> s : splited) {</div><div class="line">                <span class="keywordflow">if</span> (!s.isEmpty()) {</div><div class="line">                    homographyData[idx] = Double.parseDouble(s);</div><div class="line">                    idx++;</div><div class="line">                }</div><div class="line">            }</div><div class="line">        } <span class="keywordflow">catch</span> (ParserConfigurationException e) {</div><div class="line">            e.printStackTrace();</div><div class="line">            System.exit(0);</div><div class="line">        } <span class="keywordflow">catch</span> (SAXException e) {</div><div class="line">            e.printStackTrace();</div><div class="line">            System.exit(0);</div><div class="line">        } <span class="keywordflow">catch</span> (IOException e) {</div><div class="line">            e.printStackTrace();</div><div class="line">            System.exit(0);</div><div class="line">        }</div><div class="line">        homography.put(0, 0, homographyData);</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line">parser = argparse.ArgumentParser(description=<span class="stringliteral">&#39;Code for AKAZE local features matching tutorial.&#39;</span>)</div><div class="line">parser.add_argument(<span class="stringliteral">&#39;--input1&#39;</span>, help=<span class="stringliteral">&#39;Path to input image 1.&#39;</span>, default=<span class="stringliteral">&#39;graf1.png&#39;</span>)</div><div class="line">parser.add_argument(<span class="stringliteral">&#39;--input2&#39;</span>, help=<span class="stringliteral">&#39;Path to input image 2.&#39;</span>, default=<span class="stringliteral">&#39;graf3.png&#39;</span>)</div><div class="line">parser.add_argument(<span class="stringliteral">&#39;--homography&#39;</span>, help=<span class="stringliteral">&#39;Path to the homography matrix.&#39;</span>, default=<span class="stringliteral">&#39;H1to3p.xml&#39;</span>)</div><div class="line">args = parser.parse_args()</div><div class="line"></div><div class="line">img1 = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">cv.imread</a>(<a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">cv.samples.findFile</a>(args.input1), cv.IMREAD_GRAYSCALE)</div><div class="line">img2 = <a class="code" href="../../d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56">cv.imread</a>(<a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">cv.samples.findFile</a>(args.input2), cv.IMREAD_GRAYSCALE)</div><div class="line"><span class="keywordflow">if</span> img1 <span class="keywordflow">is</span> <span class="keywordtype">None</span> <span class="keywordflow">or</span> img2 <span class="keywordflow">is</span> <span class="keywordtype">None</span>:</div><div class="line">    <a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;Could not open or find the images!&#39;</span>)</div><div class="line">    exit(0)</div><div class="line"></div><div class="line">fs = <a class="code" href="../../da/d56/classcv_1_1FileStorage.html">cv.FileStorage</a>(<a class="code" href="../../d6/dba/group__core__utils__samples.html#ga3a33b00033b46c698ff6340d95569c13">cv.samples.findFile</a>(args.homography), cv.FILE_STORAGE_READ)</div><div class="line">homography = fs.getFirstTopLevelNode().mat()</div></div><!-- fragment --> </div> <p>We are loading grayscale images here. Homography is stored in the xml created with FileStorage.</p>
<ul>
<li><b>Detect keypoints and compute descriptors using AKAZE</b></li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    vector&lt;KeyPoint&gt; kpts1, kpts2;</div><div class="line">    Mat desc1, desc2;</div><div class="line"></div><div class="line">    Ptr&lt;AKAZE&gt; akaze = AKAZE::create();</div><div class="line">    akaze-&gt;detectAndCompute(img1, <a class="code" href="../../dc/d84/group__core__basic.html#gad9287b23bba2fed753b36ef561ae7346">noArray</a>(), kpts1, desc1);</div><div class="line">    akaze-&gt;detectAndCompute(img2, <a class="code" href="../../dc/d84/group__core__basic.html#gad9287b23bba2fed753b36ef561ae7346">noArray</a>(), kpts2, desc2);</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        AKAZE akaze = AKAZE.create();</div><div class="line">        MatOfKeyPoint kpts1 = <span class="keyword">new</span> MatOfKeyPoint(), kpts2 = <span class="keyword">new</span> MatOfKeyPoint();</div><div class="line">        Mat desc1 = <span class="keyword">new</span> Mat(), desc2 = <span class="keyword">new</span> Mat();</div><div class="line">        akaze.detectAndCompute(img1, <span class="keyword">new</span> Mat(), kpts1, desc1);</div><div class="line">        akaze.detectAndCompute(img2, <span class="keyword">new</span> Mat(), kpts2, desc2);</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line">akaze = cv.AKAZE_create()</div><div class="line">kpts1, desc1 = akaze.detectAndCompute(img1, <span class="keywordtype">None</span>)</div><div class="line">kpts2, desc2 = akaze.detectAndCompute(img2, <span class="keywordtype">None</span>)</div></div><!-- fragment --> </div> <p>We create AKAZE and detect and compute AKAZE keypoints and descriptors. Since we don't need the <em>mask</em> parameter, <em><a class="el" href="../../dc/d84/group__core__basic.html#gad9287b23bba2fed753b36ef561ae7346">noArray()</a></em> is used.</p>
<ul>
<li><b>Use brute-force matcher to find 2-nn matches</b></li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    BFMatcher matcher(<a class="code" href="../../d2/de8/group__core__array.html#ggad12cefbcb5291cf958a85b4b67b6149fa4b063afd04aebb8dd07085a1207da727">NORM_HAMMING</a>);</div><div class="line">    vector&lt; vector&lt;DMatch&gt; &gt; nn_matches;</div><div class="line">    matcher.knnMatch(desc1, desc2, nn_matches, 2);</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);</div><div class="line">        List&lt;MatOfDMatch&gt; knnMatches = <span class="keyword">new</span> ArrayList&lt;&gt;();</div><div class="line">        matcher.knnMatch(desc1, desc2, knnMatches, 2);</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line">matcher = cv.DescriptorMatcher_create(cv.DescriptorMatcher_BRUTEFORCE_HAMMING)</div><div class="line">nn_matches = matcher.knnMatch(desc1, desc2, 2)</div></div><!-- fragment --> </div> <p>We use Hamming distance, because AKAZE uses binary descriptor by default.</p>
<ul>
<li><b>Use 2-nn matches and ratio criterion to find correct keypoint matches</b>  <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    vector&lt;KeyPoint&gt; matched1, matched2;</div><div class="line">    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; nn_matches.size(); i++) {</div><div class="line">        DMatch first = nn_matches[i][0];</div><div class="line">        <span class="keywordtype">float</span> dist1 = nn_matches[i][0].<a class="code" href="../../d4/de0/classcv_1_1DMatch.html#a1cb9bee47b20ad96e16de28f4b9cbdf1">distance</a>;</div><div class="line">        <span class="keywordtype">float</span> dist2 = nn_matches[i][1].distance;</div><div class="line"></div><div class="line">        <span class="keywordflow">if</span>(dist1 &lt; nn_match_ratio * dist2) {</div><div class="line">            matched1.push_back(kpts1[first.queryIdx]);</div><div class="line">            matched2.push_back(kpts2[first.trainIdx]);</div><div class="line">        }</div><div class="line">    }</div></div><!-- fragment --> </div> </li>
</ul>
 <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        <span class="keywordtype">float</span> ratioThreshold = 0.8f; <span class="comment">// Nearest neighbor matching ratio</span></div><div class="line">        List&lt;KeyPoint&gt; listOfMatched1 = <span class="keyword">new</span> ArrayList&lt;&gt;();</div><div class="line">        List&lt;KeyPoint&gt; listOfMatched2 = <span class="keyword">new</span> ArrayList&lt;&gt;();</div><div class="line">        List&lt;KeyPoint&gt; listOfKeypoints1 = kpts1.toList();</div><div class="line">        List&lt;KeyPoint&gt; listOfKeypoints2 = kpts2.toList();</div><div class="line">        <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; knnMatches.size(); i++) {</div><div class="line">            DMatch[] matches = knnMatches.get(i).toArray();</div><div class="line">            <span class="keywordtype">float</span> dist1 = matches[0].distance;</div><div class="line">            <span class="keywordtype">float</span> dist2 = matches[1].distance;</div><div class="line">            <span class="keywordflow">if</span> (dist1 &lt; ratioThreshold * dist2) {</div><div class="line">                listOfMatched1.add(listOfKeypoints1.get(matches[0].queryIdx));</div><div class="line">                listOfMatched2.add(listOfKeypoints2.get(matches[0].trainIdx));</div><div class="line">            }</div><div class="line">        }</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line">matched1 = []</div><div class="line">matched2 = []</div><div class="line">nn_match_ratio = 0.8 <span class="comment"># Nearest neighbor matching ratio</span></div><div class="line"><span class="keywordflow">for</span> m, n <span class="keywordflow">in</span> nn_matches:</div><div class="line">    <span class="keywordflow">if</span> m.distance &lt; nn_match_ratio * n.distance:</div><div class="line">        matched1.append(kpts1[m.queryIdx])</div><div class="line">        matched2.append(kpts2[m.trainIdx])</div></div><!-- fragment --> </div> <p>If the closest match distance is significantly lower than the second closest one, then the match is correct (match is not ambiguous).</p>
<ul>
<li><b>Check if our matches fit in the homography model</b></li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    vector&lt;DMatch&gt; good_matches;</div><div class="line">    vector&lt;KeyPoint&gt; inliers1, inliers2;</div><div class="line">    <span class="keywordflow">for</span>(<span class="keywordtype">size_t</span> i = 0; i &lt; matched1.size(); i++) {</div><div class="line">        Mat col = Mat::ones(3, 1, <a class="code" href="../../d1/d1b/group__core__hal__interface.html#ga30a562691cc5987bc88eb7bb7a8faf2b">CV_64F</a>);</div><div class="line">        col.at&lt;<span class="keywordtype">double</span>&gt;(0) = matched1[i].pt.x;</div><div class="line">        col.at&lt;<span class="keywordtype">double</span>&gt;(1) = matched1[i].pt.y;</div><div class="line"></div><div class="line">        col = homography * col;</div><div class="line">        col /= col.at&lt;<span class="keywordtype">double</span>&gt;(2);</div><div class="line">        <span class="keywordtype">double</span> dist = <a class="code" href="../../d0/de1/group__core.html#ga9070b6a3f093dd952d973819b06f4906">sqrt</a>( <a class="code" href="../../d7/dcc/group__core__utils__softfloat.html#ga8bc36646a43b82baa15f151a973fb0c5">pow</a>(col.at&lt;<span class="keywordtype">double</span>&gt;(0) - matched2[i].pt.x, 2) +</div><div class="line">                            <a class="code" href="../../d7/dcc/group__core__utils__softfloat.html#ga8bc36646a43b82baa15f151a973fb0c5">pow</a>(col.at&lt;<span class="keywordtype">double</span>&gt;(1) - matched2[i].pt.y, 2));</div><div class="line"></div><div class="line">        <span class="keywordflow">if</span>(dist &lt; inlier_threshold) {</div><div class="line">            <span class="keywordtype">int</span> new_i = <span class="keyword">static_cast&lt;</span><span class="keywordtype">int</span><span class="keyword">&gt;</span>(inliers1.size());</div><div class="line">            inliers1.push_back(matched1[i]);</div><div class="line">            inliers2.push_back(matched2[i]);</div><div class="line">            good_matches.push_back(DMatch(new_i, new_i, 0));</div><div class="line">        }</div><div class="line">    }</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        <span class="keywordtype">double</span> inlierThreshold = 2.5; <span class="comment">// Distance threshold to identify inliers with homography check</span></div><div class="line">        List&lt;KeyPoint&gt; listOfInliers1 = <span class="keyword">new</span> ArrayList&lt;&gt;();</div><div class="line">        List&lt;KeyPoint&gt; listOfInliers2 = <span class="keyword">new</span> ArrayList&lt;&gt;();</div><div class="line">        List&lt;DMatch&gt; listOfGoodMatches = <span class="keyword">new</span> ArrayList&lt;&gt;();</div><div class="line">        <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i &lt; listOfMatched1.size(); i++) {</div><div class="line">            Mat col = <span class="keyword">new</span> Mat(3, 1, CvType.CV_64F);</div><div class="line">            <span class="keywordtype">double</span>[] colData = <span class="keyword">new</span> <span class="keywordtype">double</span>[(int) (col.total() * col.channels())];</div><div class="line">            colData[0] = listOfMatched1.get(i).pt.x;</div><div class="line">            colData[1] = listOfMatched1.get(i).pt.y;</div><div class="line">            colData[2] = 1.0;</div><div class="line">            col.put(0, 0, colData);</div><div class="line"></div><div class="line">            Mat colRes = <span class="keyword">new</span> Mat();</div><div class="line">            Core.gemm(homography, col, 1.0, <span class="keyword">new</span> Mat(), 0.0, colRes);</div><div class="line">            colRes.get(0, 0, colData);</div><div class="line">            Core.multiply(colRes, <span class="keyword">new</span> <a class="code" href="../../dc/d84/group__core__basic.html#ga599fe92e910c027be274233eccad7beb">Scalar</a>(1.0 / colData[2]), col);</div><div class="line">            col.get(0, 0, colData);</div><div class="line"></div><div class="line">            <span class="keywordtype">double</span> dist = Math.sqrt(Math.pow(colData[0] - listOfMatched2.get(i).pt.x, 2) +</div><div class="line">                    Math.pow(colData[1] - listOfMatched2.get(i).pt.y, 2));</div><div class="line"></div><div class="line">            <span class="keywordflow">if</span> (dist &lt; inlierThreshold) {</div><div class="line">                listOfGoodMatches.add(<span class="keyword">new</span> DMatch(listOfInliers1.size(), listOfInliers2.size(), 0));</div><div class="line">                listOfInliers1.add(listOfMatched1.get(i));</div><div class="line">                listOfInliers2.add(listOfMatched2.get(i));</div><div class="line">            }</div><div class="line">        }</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line">inliers1 = []</div><div class="line">inliers2 = []</div><div class="line">good_matches = []</div><div class="line">inlier_threshold = 2.5 <span class="comment"># Distance threshold to identify inliers with homography check</span></div><div class="line"><span class="keywordflow">for</span> i, m <span class="keywordflow">in</span> enumerate(matched1):</div><div class="line">    col = np.ones((3,1), dtype=np.float64)</div><div class="line">    col[0:2,0] = m.pt</div><div class="line"></div><div class="line">    col = np.dot(homography, col)</div><div class="line">    col /= col[2,0]</div><div class="line">    dist = <a class="code" href="../../d0/de1/group__core.html#ga9070b6a3f093dd952d973819b06f4906">sqrt</a>(<a class="code" href="../../d7/dcc/group__core__utils__softfloat.html#ga8bc36646a43b82baa15f151a973fb0c5">pow</a>(col[0,0] - matched2[i].pt[0], 2) +\</div><div class="line">                <a class="code" href="../../d7/dcc/group__core__utils__softfloat.html#ga8bc36646a43b82baa15f151a973fb0c5">pow</a>(col[1,0] - matched2[i].pt[1], 2))</div><div class="line"></div><div class="line">    <span class="keywordflow">if</span> dist &lt; inlier_threshold:</div><div class="line">        good_matches.append(<a class="code" href="../../d4/de0/classcv_1_1DMatch.html">cv.DMatch</a>(len(inliers1), len(inliers2), 0))</div><div class="line">        inliers1.append(matched1[i])</div><div class="line">        inliers2.append(matched2[i])</div></div><!-- fragment --> </div> <p>If the distance from first keypoint's projection to the second keypoint is less than threshold, then it fits the homography model.</p>
<p>We create a new set of matches for the inliers, because it is required by the drawing function.</p>
<ul>
<li><b>Output results</b></li>
</ul>
 <div class='newInnerHTML' title='cpp' style='display: none;'>C++</div><div class='toggleable_div label_cpp' style='display: none;'> <div class="fragment"><div class="line">    Mat res;</div><div class="line">    <a class="code" href="../../d4/d5d/group__features2d__draw.html#gad8f463ccaf0dc6f61083abd8717c261a">drawMatches</a>(img1, inliers1, img2, inliers2, good_matches, res);</div><div class="line">    <a class="code" href="../../d4/da8/group__imgcodecs.html#gabbc7ef1aa2edfaa87772f1202d67e0ce">imwrite</a>(<span class="stringliteral">&quot;akaze_result.png&quot;</span>, res);</div><div class="line"></div><div class="line">    <span class="keywordtype">double</span> inlier_ratio = inliers1.size() / (double) matched1.size();</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;A-KAZE Matching Results&quot;</span> &lt;&lt; endl;</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;*******************************&quot;</span> &lt;&lt; endl;</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;# Keypoints 1:                        \t&quot;</span> &lt;&lt; kpts1.size() &lt;&lt; endl;</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;# Keypoints 2:                        \t&quot;</span> &lt;&lt; kpts2.size() &lt;&lt; endl;</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;# Matches:                            \t&quot;</span> &lt;&lt; matched1.size() &lt;&lt; endl;</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;# Inliers:                            \t&quot;</span> &lt;&lt; inliers1.size() &lt;&lt; endl;</div><div class="line">    cout &lt;&lt; <span class="stringliteral">&quot;# Inliers Ratio:                      \t&quot;</span> &lt;&lt; inlier_ratio &lt;&lt; endl;</div><div class="line">    cout &lt;&lt; endl;</div><div class="line"></div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#ga453d42fe4cb60e5723281a89973ee563">imshow</a>(<span class="stringliteral">&quot;result&quot;</span>, res);</div><div class="line">    <a class="code" href="../../d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba38bd7">waitKey</a>();</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='java' style='display: none;'>Java</div><div class='toggleable_div label_java' style='display: none;'> <div class="fragment"><div class="line">        Mat res = <span class="keyword">new</span> Mat();</div><div class="line">        MatOfKeyPoint inliers1 = <span class="keyword">new</span> MatOfKeyPoint(listOfInliers1.toArray(<span class="keyword">new</span> KeyPoint[listOfInliers1.size()]));</div><div class="line">        MatOfKeyPoint inliers2 = <span class="keyword">new</span> MatOfKeyPoint(listOfInliers2.toArray(<span class="keyword">new</span> KeyPoint[listOfInliers2.size()]));</div><div class="line">        MatOfDMatch goodMatches = <span class="keyword">new</span> MatOfDMatch(listOfGoodMatches.toArray(<span class="keyword">new</span> DMatch[listOfGoodMatches.size()]));</div><div class="line">        Features2d.drawMatches(img1, inliers1, img2, inliers2, goodMatches, res);</div><div class="line">        Imgcodecs.imwrite(<span class="stringliteral">&quot;akaze_result.png&quot;</span>, res);</div><div class="line"></div><div class="line">        <span class="keywordtype">double</span> inlierRatio = listOfInliers1.size() / (double) listOfMatched1.size();</div><div class="line">        System.out.println(<span class="stringliteral">&quot;A-KAZE Matching Results&quot;</span>);</div><div class="line">        System.out.println(<span class="stringliteral">&quot;*******************************&quot;</span>);</div><div class="line">        System.out.println(<span class="stringliteral">&quot;# Keypoints 1:                        \t&quot;</span> + listOfKeypoints1.size());</div><div class="line">        System.out.println(<span class="stringliteral">&quot;# Keypoints 2:                        \t&quot;</span> + listOfKeypoints2.size());</div><div class="line">        System.out.println(<span class="stringliteral">&quot;# Matches:                            \t&quot;</span> + listOfMatched1.size());</div><div class="line">        System.out.println(<span class="stringliteral">&quot;# Inliers:                            \t&quot;</span> + listOfInliers1.size());</div><div class="line">        System.out.println(<span class="stringliteral">&quot;# Inliers Ratio:                      \t&quot;</span> + inlierRatio);</div><div class="line"></div><div class="line">        HighGui.imshow(<span class="stringliteral">&quot;result&quot;</span>, res);</div><div class="line">        HighGui.waitKey();</div></div><!-- fragment --> </div>  <div class='newInnerHTML' title='python' style='display: none;'>Python</div><div class='toggleable_div label_python' style='display: none;'> <div class="fragment"><div class="line">res = np.empty((<a class="code" href="../../d1/d10/classcv_1_1MatExpr.html#a6dff8b6e9105b6d817b493e7be157c90">max</a>(img1.shape[0], img2.shape[0]), img1.shape[1]+img2.shape[1], 3), dtype=np.uint8)</div><div class="line"><a class="code" href="../../d4/d5d/group__features2d__draw.html#ga62fbedb5206ab2faf411797e7055c90f">cv.drawMatches</a>(img1, inliers1, img2, inliers2, good_matches, res)</div><div class="line"><a class="code" href="../../d4/da8/group__imgcodecs.html#gabbc7ef1aa2edfaa87772f1202d67e0ce">cv.imwrite</a>(<span class="stringliteral">&quot;akaze_result.png&quot;</span>, res)</div><div class="line"></div><div class="line">inlier_ratio = len(inliers1) / float(len(matched1))</div><div class="line"><a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;A-KAZE Matching Results&#39;</span>)</div><div class="line"><a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;*******************************&#39;</span>)</div><div class="line"><a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;# Keypoints 1:                        \t&#39;</span>, len(kpts1))</div><div class="line"><a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;# Keypoints 2:                        \t&#39;</span>, len(kpts2))</div><div class="line"><a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;# Matches:                            \t&#39;</span>, len(matched1))</div><div class="line"><a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;# Inliers:                            \t&#39;</span>, len(inliers1))</div><div class="line"><a class="code" href="../../df/d57/namespacecv_1_1dnn.html#a701210a0203f2786cbfd04b2bd56da47">print</a>(<span class="stringliteral">&#39;# Inliers Ratio:                      \t&#39;</span>, inlier_ratio)</div><div class="line"></div><div class="line"><a class="code" href="../../df/d24/group__highgui__opengl.html#gaae7e90aa3415c68dba22a5ff2cefc25d">cv.imshow</a>(<span class="stringliteral">&#39;result&#39;</span>, res)</div><div class="line"><a class="code" href="../../d7/dfc/group__highgui.html#ga5628525ad33f52eab17feebcfba38bd7">cv.waitKey</a>()</div></div><!-- fragment --> </div> <p>Here we save the resulting image and print some statistics.</p>
<h2>Results </h2>
<h3>Found matches</h3>
<div class="image">
<img src="../../res.png" alt="res.png"/>
</div>
<p>Depending on your OpenCV version, you should get results coherent with:</p>
<div class="fragment"><div class="line">Keypoints 1:   2943</div><div class="line">Keypoints 2:   3511</div><div class="line">Matches:       447</div><div class="line">Inliers:       308</div><div class="line">Inlier Ratio: 0.689038</div></div><!-- fragment --> </div></div><!-- contents -->
<!-- HTML footer for doxygen 1.8.6-->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Apr 2 2021 11:36:34 for OpenCV by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="../../doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
<script type="text/javascript">
//<![CDATA[
addTutorialsButtons();
//]]>
</script>
</body>
</html>
